using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using NLog;
using Vin.Extension.Framework.Alipay.Adapter;
using Vin.Extension.Framework.Alipay.Models;
using Vin.Extension.Framework.Alipay.Service;
using Vin.Tool.AspNetCore.Singleton;
using Vin.Tool.Core.AssemblyCategory;
using Vin.Tool.Core.JsonCategory;
using Vin.Tool.Core.NetCategory;

namespace Vin.Extension.Framework.Alipay;

public class AlipayEndpoint
{
    private static List<IAlipayNotify> Callbacks => AssemblyTool.GetTypes<IAlipayNotify>()
        .Select(Activator.CreateInstance)
        .Cast<IAlipayNotify>()
        .ToList();

    public static void UseAlipayNotify(WebApplication app, string notifyUrl)
    {
        app.MapPost(notifyUrl, async (HttpRequest request) =>
        {
            var context = request.HttpContext;
            var logger = VinApp.GetRequiredServiceByHttpContext<ILogger<AlipayEndpoint>>();
            var vinAlipaySignatureService = VinApp.GetRequiredServiceByHttpContext<VinAlipaySignatureService>();
            if (!vinAlipaySignatureService.PaySignatureCertVerifyV2Async())
            {
                logger.LogError("支付宝支付成功回调签名验证失败: {0}", context.FormDictionary().ToCamelCaseJson());
            }
            else
            {
                var dto = context.FormToObject<AlipayNotifyModel>(JsonTool.JsonOptionsType.UnderLineLower);
                foreach (var alipayNotify in Callbacks
                             .Where(x => x.MsgMethod == dto.MsgMethod || x.NotifyType == dto.NotifyType)
                             .OrderBy(m => m.Order))
                {
                    await alipayNotify.NotifyAsync(context, dto);
                }
            }

            return TypedResults.Content("success");
        });
    }
}